home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gsdevmem.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  7KB  |  217 lines

  1. /* Copyright (C) 1995 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsdevmem.c */
  20. /* Memory device creation for Ghostscript library */
  21. #include "math_.h"            /* for fabs */
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gxarith.h"
  26. #include "gxdevice.h"
  27. #include "gxdevmem.h"
  28.  
  29. /* Make a memory (image) device. */
  30. /* If colors_size = -16, -24, or -32, this is a true-color device; */
  31. /* otherwise, colors_size is the size of the palette in bytes */
  32. /* (2^N for gray scale, 3*2^N for RGB color). */
  33. /* We separate device allocation and initialization at customer request. */
  34. int
  35. gs_initialize_wordimagedevice(gx_device_memory *new_dev, const gs_matrix *pmat,
  36.   uint width, uint height, const byte *colors, int colors_size,
  37.   bool word_oriented, bool page_device, gs_memory_t *mem)
  38. {    const gx_device_memory *proto_dev;
  39.     int palette_count = colors_size;
  40.     int num_components = 1;
  41.     int pcount;
  42.     int bits_per_pixel;
  43.     float x_pixels_per_unit, y_pixels_per_unit;
  44.     byte palette[256 * 3];
  45.     byte *dev_palette;
  46.     bool has_color;
  47.     switch ( colors_size )
  48.        {
  49.     case 3*2:
  50.         palette_count = 2; num_components = 3;
  51.     case 2:
  52.         bits_per_pixel = 1; break;
  53.     case 3*4:
  54.         palette_count = 4; num_components = 3;
  55.     case 4:
  56.         bits_per_pixel = 2; break;
  57.     case 3*16:
  58.         palette_count = 16; num_components = 3;
  59.     case 16:
  60.         bits_per_pixel = 4; break;
  61.     case 3*256:
  62.         palette_count = 256; num_components = 3;
  63.     case 256:
  64.         bits_per_pixel = 8; break;
  65.     case -16:
  66.         bits_per_pixel = 16; palette_count = 0; break;
  67.     case -24:
  68.         bits_per_pixel = 24; palette_count = 0; break;
  69.     case -32:
  70.         bits_per_pixel = 32; palette_count = 0; break;
  71.     default:
  72.         return_error(gs_error_rangecheck);
  73.        }
  74.     proto_dev = (word_oriented ?
  75.              gdev_mem_word_device_for_bits(bits_per_pixel) :
  76.              gdev_mem_device_for_bits(bits_per_pixel));
  77.     if ( proto_dev == 0 )        /* no suitable device */
  78.       return_error(gs_error_rangecheck);
  79.     pcount = palette_count * 3;
  80.     /* Check to make sure the palette contains white and black, */
  81.     /* and, if it has any colors, the six primaries. */
  82.     if ( bits_per_pixel <= 8 )
  83.        {    const byte *p;
  84.         byte *q;
  85.         int primary_mask = 0;
  86.         int i;
  87.  
  88.         has_color = false;
  89.         for ( i = 0, p = colors, q = palette;
  90.               i < palette_count; i++, q += 3
  91.             )
  92.            {    int mask = 1;
  93.             switch ( num_components )
  94.                {
  95.             case 1:            /* gray */
  96.                 q[0] = q[1] = q[2] = *p++;
  97.                 break;
  98.             default /* case 3 */:    /* RGB */
  99.                 q[0] = p[0], q[1] = p[1], q[2] = p[2];
  100.                 p += 3;
  101.                }
  102. #define shift_mask(b,n)\
  103.   switch ( b ) { case 0xff: mask <<= n; case 0: break; default: mask = 0; }
  104.             shift_mask(q[0], 4);
  105.             shift_mask(q[1], 2);
  106.             shift_mask(q[2], 1);
  107. #undef shift_mask
  108.             primary_mask |= mask;
  109.             if ( q[0] != q[1] || q[0] != q[2] )
  110.               has_color = true;
  111.            }
  112.         switch ( primary_mask )
  113.            {
  114.         case 129:        /* just black and white */
  115.             if ( has_color )    /* color but no primaries */
  116.               return_error(gs_error_rangecheck);
  117.         case 255:        /* full color */
  118.             break;
  119.         default:
  120.             return_error(gs_error_rangecheck);
  121.            }
  122.        }
  123.     else
  124.         has_color = true;
  125.     /*
  126.      * The initial transformation matrix must map 1 user unit to
  127.      * 1/72".  Let W and H be the width and height in pixels, and
  128.      * assume the initial matrix is of the form [A 0 0 B X Y].
  129.      * Then the size of the image in user units is (W/|A|,H/|B|),
  130.      * hence the size in inches is ((W/|A|)/72,(H/|B|)/72), so
  131.      * the number of pixels per inch is
  132.      * (W/((W/|A|)/72),H/((H/|B|)/72)), or (|A|*72,|B|*72).
  133.      * Similarly, if the initial matrix is [0 A B 0 X Y] for a 90
  134.      * or 270 degree rotation, the size of the image in user
  135.      * units is (W/|B|,H/|A|), so the pixels per inch are
  136.      * (|B|*72,|A|*72).  We forbid non-orthogonal transformation
  137.      * matrices.
  138.      */
  139.     if ( is_fzero2(pmat->xy, pmat->yx) )
  140.       x_pixels_per_unit = pmat->xx, y_pixels_per_unit = pmat->yy;
  141.     else if ( is_fzero2(pmat->xx, pmat->yy) )
  142.       x_pixels_per_unit = pmat->yx, y_pixels_per_unit = pmat->xy;
  143.     else
  144.       return_error(gs_error_undefinedresult);
  145.     /* All checks done, allocate the device. */
  146.     if ( bits_per_pixel != 1 )
  147.       { dev_palette = gs_alloc_string(mem, pcount,
  148.                       "gs_makeimagedevice(palette)");
  149.         if ( dev_palette == 0 )
  150.           return_error(gs_error_VMerror);
  151.       }
  152.     gs_make_mem_device(new_dev, proto_dev, mem,
  153.                (page_device ? 1 : -1), 0);
  154.     if ( !has_color )
  155.       {    new_dev->color_info.num_components = 1;
  156.         new_dev->color_info.max_color = 0;
  157.         new_dev->color_info.dither_colors = 0;
  158.       }
  159.     if ( bits_per_pixel == 1 )
  160.       {    /* Determine the polarity from the palette. */
  161.         /* This is somewhat bogus, but does the right thing */
  162.         /* in the only cases we care about. */
  163.         gdev_mem_mono_set_inverted(new_dev,
  164.             (palette[0] | palette[1] | palette[2]) != 0);
  165.       }
  166.     else
  167.       {    new_dev->palette.size = pcount;
  168.         new_dev->palette.data = dev_palette;
  169.         memcpy(dev_palette, palette, pcount);
  170.       }
  171.     new_dev->initial_matrix = *pmat;
  172.     new_dev->MarginsHWResolution[0] = new_dev->HWResolution[0] =
  173.       fabs(x_pixels_per_unit) * 72;
  174.     new_dev->MarginsHWResolution[1] = new_dev->HWResolution[1] =
  175.       fabs(y_pixels_per_unit) * 72;
  176.     gx_device_set_width_height((gx_device *)new_dev, width, height);
  177.     /* Set the ImagingBBox so we get a correct clipping region. */
  178.     { gs_rect bbox;
  179.       bbox.p.x = 0;
  180.       bbox.p.y = 0;
  181.       bbox.q.x = width;
  182.       bbox.q.y = height;
  183.       gs_bbox_transform_inverse(&bbox, pmat, &bbox);
  184.       new_dev->ImagingBBox[0] = bbox.p.x;
  185.       new_dev->ImagingBBox[1] = bbox.p.y;
  186.       new_dev->ImagingBBox[2] = bbox.q.x;
  187.       new_dev->ImagingBBox[3] = bbox.q.y;
  188.       new_dev->ImagingBBox_set = true;
  189.     }
  190.     /* The bitmap will be allocated when the device is opened. */
  191.     new_dev->is_open = false;
  192.     new_dev->bitmap_memory = mem;
  193.     return 0;
  194. }
  195.  
  196. int
  197. gs_makewordimagedevice(gx_device **pnew_dev, const gs_matrix *pmat,
  198.   uint width, uint height, const byte *colors, int num_colors,
  199.   bool word_oriented, bool page_device, gs_memory_t *mem)
  200. {    int code;
  201.     gx_device_memory *pnew =
  202.       gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
  203.               "gs_makeimagedevice(device)");
  204.  
  205.     if (pnew == 0)
  206.           return_error (gs_error_VMerror);
  207.         code = gs_initialize_wordimagedevice(pnew, pmat, width, height,
  208.                          colors, num_colors, word_oriented,
  209.                          page_device, mem);
  210.         if (code < 0)
  211.       {    gs_free_object(mem, pnew, "gs_makeimagedevice(device)");
  212.         return code;
  213.       }
  214.         *pnew_dev = (gx_device *)pnew;
  215.         return 0;
  216. }
  217.